package com.yang.simple_rpc.client.net;

import com.yang.simple_rpc.client.net.handler.SendHandler;
import com.yang.simple_rpc.common.service.Service;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @author : morikawaaaa
 * @date : 2022
 */
public class NettyNetClient implements NetClient{

    private static Logger logger = LoggerFactory.getLogger(NettyNetClient.class);
    @Override
    public byte[] sendRequest(byte[] bytes, Service service) throws InterruptedException {
        String[] serviceAddressInfo = service.getAddress().split(":");
        String serviceAddress = serviceAddressInfo[0];
        String port = serviceAddressInfo[1];
        SendHandler sh = new SendHandler(bytes);
        byte[] resp;
        EventLoopGroup group = new NioEventLoopGroup();

        try{
            Bootstrap b = new Bootstrap();
            b.group(group)
                    //NioSocketChannel,这个类在客户端channel 被创建时使用
                    .channel(NioSocketChannel.class)
                    //该参数的作用就是禁止使用Nagle算法，使用于小数据即时传输（不进行数据包组装为更大的帧然后进行发送）
                    //不像在使用 ServerBootstrap 时需要用 childOption() 方法，因为客户端的 SocketChannel 没有父亲
                    .option(ChannelOption.TCP_NODELAY, true)
                    //ChannelInitializer就是ChannelInboundHandler的实现,就是将来辅助生产pipeline的,pipeline是一个handler链表
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel sc){
                            ChannelPipeline p = sc.pipeline();
                            p.addLast(sh);
                        }
                    });

            b.connect(serviceAddress, Integer.valueOf(port)).sync();
            resp = (byte[]) sh.rspData();
            logger.info("SendRequest get reply : {}", resp);
        }finally{
            group.shutdownGracefully();
        }

        return resp;



    }
}
